/**
 * Filename: send_idinfo.c
 * Created on: 2013-8-30
 * Author: berryha
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
//#include <sys/ioctl.h>  
#include <sys/fcntl.h>
#include "USER_CFG.h"
#include <errno.h>
#define MAXLINE 1024
#define SERV_PORT 10000
#define FIFO	"/fifo"

char str[1024*10];
char str1[1024*10];
char buffer[1024*10];

int str_flag = 0;
_enum_DMODE G_DispMode = dmode_0C;
extern unsigned int GUI_LCM_XMAX,GUI_LCM_YMAX;
extern REGION G_REG_DIR;
extern REGION G_REG_FLR;
extern REGION G_REG_TIME;
extern REGION G_REG_DAY;
extern REGION G_REG_WEEK;
extern REGION G_REG_ALARM;
extern REGION G_REG_BKGND;
extern REGION G_REG_LOGO;
extern REGION G_REG_OTHER;
extern REGION G_REG_VIDEO;
extern REGION G_REG_TXT;
unsigned int BKGND_wait;
unsigned int BKGND_effect;

extern unsigned int G_LFTTXT_txt_vfmode;
extern unsigned int G_LFTTXT_vf_speed;
extern unsigned int G_LFTTXT_txt_color;

REGION G_REG_DIR_T2;
REGION G_REG_FLR_T2;
REGION G_REG_ALARM_T2;
REGION REG_DES;

char itos[20];
char client_id[40];
char botrunstart[2];
char botdoorstart[2];
char botfloor[4];
char botstart[2];
char currentmedia[40];
char currentdownload[40];
char mediavolume[4];
char net_status[4];
char net_status[4];
char static_ip[40];
char macid[20];
char* int_to_str(int n)
{	
	memset(itos,0,20);
	sprintf(itos,"%d",n);
	return itos;
}


int creat_xml_file()
{
	int vol;
	char starttime[20];
	

	G_DispMode = GetSysCfg();
	
	G_REG_VIDEO.x_len = G_REG_VIDEO.x_len/2*2;
	G_REG_VIDEO.y_len = G_REG_VIDEO.y_len/2*2;
	
	FILE *VOLUME = fopen("/mnt/bootdev/volume.cfg","rb");
	if(VOLUME!=NULL)
	{	     
		vol=fgetc(VOLUME);	
		fclose(VOLUME);
	}
	else
	vol = 20;

	memset(mediavolume,0,4);
	sprintf(mediavolume,"%d",vol);

	FILE *starttime_fp=fopen("/start_time","r");
	memset(starttime,0,20);
	if(starttime_fp!=NULL)
	{	     
		fgets(starttime,20,starttime_fp);
		fclose(starttime_fp);
	}

	FILE *mac_fp=fopen("/v4asys/mac","r");
	memset(macid,0,20);
	if(mac_fp!=NULL)
	{	     
		fgets(macid,20,mac_fp);
		fclose(mac_fp);
	}

	mac_fp=fopen("/v4asys/terminal_ip","r");
	memset(static_ip,0,40);
	if(mac_fp!=NULL)
	{	     
		fgets(static_ip,40,mac_fp);
		fclose(mac_fp);
	}


	xmlDocPtr doc = NULL;         /* document pointer */
	xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;/* node pointers */

	// Creates a new document, a node and set it as a root node
	doc = xmlNewDoc(BAD_CAST "1.0");
	root_node = xmlNewNode(NULL, BAD_CAST "clientinfo");
	xmlDocSetRootElement(doc, root_node);

	xmlNewChild(root_node, NULL, BAD_CAST "terminalid",BAD_CAST macid);
	xmlNewChild(root_node, NULL, BAD_CAST "terminalversion",BAD_CAST "V4A02_2.3.8");
	xmlNewChild(root_node, NULL, BAD_CAST "macid",BAD_CAST macid);
	xmlNewChild(root_node, NULL, BAD_CAST "macenable",BAD_CAST "true");
	xmlNewChild(root_node, NULL, BAD_CAST "staticip",BAD_CAST static_ip);
	xmlNewChild(root_node, NULL, BAD_CAST "screenxlen",BAD_CAST int_to_str(GUI_LCM_XMAX));
	xmlNewChild(root_node, NULL, BAD_CAST "screenylen",BAD_CAST int_to_str(GUI_LCM_YMAX));

	xmlNewChild(root_node, NULL, BAD_CAST "videoxstart",BAD_CAST int_to_str(G_REG_VIDEO.s_x));
	xmlNewChild(root_node, NULL, BAD_CAST "videoystart",BAD_CAST int_to_str(G_REG_VIDEO.s_y));
	xmlNewChild(root_node, NULL, BAD_CAST "videoxlen",BAD_CAST int_to_str(G_REG_VIDEO.x_len));
	xmlNewChild(root_node, NULL, BAD_CAST "videoylen",BAD_CAST int_to_str(G_REG_VIDEO.y_len));
	
	xmlNewChild(root_node, NULL, BAD_CAST "bgxstart",BAD_CAST int_to_str(G_REG_BKGND.s_x));
	xmlNewChild(root_node, NULL, BAD_CAST "bgystart",BAD_CAST int_to_str(G_REG_BKGND.s_y));
	xmlNewChild(root_node, NULL, BAD_CAST "bgxlen",BAD_CAST int_to_str(G_REG_BKGND.x_len));
	xmlNewChild(root_node, NULL, BAD_CAST "bgylen",BAD_CAST int_to_str(G_REG_BKGND.y_len));
	
	xmlNewChild(root_node, NULL, BAD_CAST "logoxstart",BAD_CAST int_to_str(G_REG_LOGO.s_x));
	xmlNewChild(root_node, NULL, BAD_CAST "logoystart",BAD_CAST int_to_str(G_REG_LOGO.s_y));
	xmlNewChild(root_node, NULL, BAD_CAST "logoxlen",BAD_CAST int_to_str(G_REG_LOGO.x_len));
	xmlNewChild(root_node, NULL, BAD_CAST "logoylen",BAD_CAST int_to_str(G_REG_LOGO.y_len));

	xmlNewChild(root_node, NULL, BAD_CAST "textxstart",BAD_CAST int_to_str(G_REG_TXT.s_x));
	xmlNewChild(root_node, NULL, BAD_CAST "textystart",BAD_CAST int_to_str(G_REG_TXT.s_y));
	xmlNewChild(root_node, NULL, BAD_CAST "textxlen",BAD_CAST int_to_str(G_REG_TXT.x_len));
	xmlNewChild(root_node, NULL, BAD_CAST "textylen",BAD_CAST int_to_str(G_REG_TXT.y_len));

	xmlNewChild(root_node, NULL, BAD_CAST "weatherxstart",BAD_CAST int_to_str(G_REG_OTHER.s_x));
	xmlNewChild(root_node, NULL, BAD_CAST "weatherystart",BAD_CAST int_to_str(G_REG_OTHER.s_y));
	xmlNewChild(root_node, NULL, BAD_CAST "weatherxlen",BAD_CAST int_to_str(G_REG_OTHER.x_len));
	xmlNewChild(root_node, NULL, BAD_CAST "weatherylen",BAD_CAST int_to_str(G_REG_OTHER.y_len));

	xmlNewChild(root_node, NULL, BAD_CAST "teminalnet",BAD_CAST "3");
	xmlNewChild(root_node, NULL, BAD_CAST "mediaangle",BAD_CAST int_to_str(G_DispMode));
	xmlNewChild(root_node, NULL, BAD_CAST "mediavolume",BAD_CAST int_to_str(vol));
	xmlNewChild(root_node, NULL, BAD_CAST "systemvolume",BAD_CAST "50");
	xmlNewChild(root_node, NULL, BAD_CAST "brightness",BAD_CAST "5");
	xmlNewChild(root_node, NULL, BAD_CAST "sleeping",BAD_CAST "15");

	//xmlNewChild(root_node, NULL, BAD_CAST "iotid",BAD_CAST "");
	//xmlNewChild(root_node, NULL, BAD_CAST "iotserver",BAD_CAST "");
	xmlNewChild(root_node, NULL, BAD_CAST "systemstarttime",BAD_CAST starttime);
	xmlNewChild(root_node, NULL, BAD_CAST "systemcurrenttime",BAD_CAST "");
	xmlNewChild(root_node, NULL, BAD_CAST "currentmedia",BAD_CAST "");
	xmlNewChild(root_node, NULL, BAD_CAST "currentdownload",BAD_CAST "");

	xmlNewChild(root_node, NULL, BAD_CAST "botrunstart",BAD_CAST "2");//上下
	xmlNewChild(root_node, NULL, BAD_CAST "botdoorstart",BAD_CAST "0");//开关
	xmlNewChild(root_node, NULL, BAD_CAST "botfloor",BAD_CAST "0");//楼层
	xmlNewChild(root_node, NULL, BAD_CAST "botstart",BAD_CAST "0");//状态

	xmlSaveFormatFileEnc("/info.xml", doc, "UTF-8", 1);

	/*free the document */
	xmlFreeDoc(doc);
	//xmlCleanupParser();
	xmlMemoryDump();//debug memory for regression tests
	return(0);
}


int  send_cmd( char  *cmd) //通过有名管道向mplayer发送命令   
{  
	int fifo_fd;
	if ((fifo_fd=open(FIFO,O_RDWR))==-1)  
		{  
			perror("open" );  
			return 1;   
		}    
	if ((write(fifo_fd,cmd,strlen(cmd)))!=strlen(cmd))  
	{  
		perror("write cmd" ); 
		return 1;
	}  
	close(fifo_fd);
	return -1;
}  

int parse_xml_file(char *buf,int len)//解析服务器下发配置参数
{ 
FILE *VOLUME;
int vol;
char setvol[20];
xmlDocPtr doc=NULL;
xmlNodePtr    cur=NULL;
char* name=NULL;
char* value=NULL;
xmlKeepBlanksDefault (0);//忽略空白行 
doc=xmlParseMemory(buf,len);//创建Dom树
if(doc==NULL)
{
   printf("Loading xml file failed.\n");
   return(1); 
}
cur=xmlDocGetRootElement(doc);//获取根节点
if(cur==NULL)
{
   printf("empty file\n");
   xmlFreeDoc(doc); 
   return(2); 
}
			 //walk the tree 
cur=cur->xmlChildrenNode;//get sub node
while(cur !=NULL)
{
   //name=(char*)(cur->name); 
   //value=(char*)xmlNodeGetContent(cur);
   if( (!xmlStrcmp(cur->name, (const xmlChar *)"rtuinfo")) )  
   {
	   value=(char*)xmlGetProp(cur,BAD_CAST"mediavolume");
	   printf("mediavolume = %s\n",value);
	   if(value!=NULL)
	   {
	   memset(setvol,0,20);
	   sscanf(value,"%d",&vol);
	   sprintf(setvol,"volume %d 1\n",vol);
	   send_cmd(setvol);

	   memset(mediavolume,0,4);
	   sprintf(mediavolume,"%d",vol);

	   VOLUME = fopen("/mnt/bootdev/volume.cfg","wb");
	   fputc(vol,VOLUME);
	   fclose(VOLUME);
	   system("sync");
	   }
	   xmlFree(value); 

	   value=(char*)xmlGetProp(cur,BAD_CAST"setip");
	   if(value!=NULL)
	   {

		   if( !strcmp(value, static_ip) )
		   {
			;
		   }
		   else if( strcmp(value, "0.0.0.0") )  
		   {
			sprintf(static_ip,"%s",value);
			VOLUME=fopen("/v4asys/terminal_ip","w");
				fwrite(value,strlen(value),1,VOLUME);
			fclose(VOLUME);
		   }
		   xmlFree(value);
		}
	   value=(char*)xmlGetProp(cur,BAD_CAST"setmac");
	   
	   if(value!=NULL)
	   {
		   if( !strcmp(value, macid) )
		   {
			;
		   }
		   else if( strcmp(value, "00.00.00.00.00.00") )  
		   {
				sprintf(macid,"%s",value);
				VOLUME=fopen("/v4asys/mac","w");
					fwrite(value,strlen(value),1,VOLUME);
				fclose(VOLUME);
				system("sync");
				sleep(2);				
				system("reboot");
		   }
		   xmlFree(value);
		}
		
	   value=(char*)xmlGetProp(cur,BAD_CAST"reboot");
	   if(value!=NULL)
	   {
		   if( !strcmp(value, "1") )  
		   {
				system("sync");
				system("reboot");
		   }
		   xmlFree(value);
	   }
   }
   cur=cur->next;
}

xmlFreeDoc(doc);//释放xml解析库所用资源
xmlCleanupParser();
return 0; 
}

int parse_xml_file1(char *buf,int len)
{ 
FILE *VOLUME;
int vol;
xmlChar *xmlbuff;  
int buffersize;
char setvol[20];
xmlDocPtr doc=NULL;
xmlNodePtr    cur=NULL;
char* name=NULL;
char* value=NULL;
xmlKeepBlanksDefault (0);//忽略空白行 
doc=xmlParseMemory(buf,len);//创建Dom树
if(doc==NULL)
{
   printf("Loading xml stream failed.\n");
   return(1); 
}
cur=xmlDocGetRootElement(doc);//获取根节点
if(cur==NULL)
{
   printf("empty file\n");
   xmlFreeDoc(doc); 
   return(2); 
}
			 //walk the tree 
cur=cur->xmlChildrenNode;//get sub node
while(cur !=NULL)
{

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"staticip")) )  
   {
	 xmlNodeSetContent(cur,static_ip);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"botrunstart")) )  
   {
	 xmlNodeSetContent(cur,botrunstart);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"botdoorstart")) )  
   {
	 xmlNodeSetContent(cur,botdoorstart); 
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"botfloor")) )  
   {
	 xmlNodeSetContent(cur,botfloor);
	//printf("%s\n",botfloor);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"botstart")) )  
   {
	 xmlNodeSetContent(cur,botstart); 
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"currentmedia")) )
   {
   	xmlNodeSetContent(cur,currentmedia);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"currentdownload")) )
   {
   	xmlNodeSetContent(cur,currentdownload);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"mediavolume")) )
   {
	
   	xmlNodeSetContent(cur,mediavolume);
   }

   if( (!xmlStrcmp(cur->name, (const xmlChar *)"teminalnet")) )
   {
		
   	xmlNodeSetContent(cur,"4");
   }


   cur=cur->next;
}
xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
//printf("%s",(char*)xmlbuff);

while(str_flag)
usleep(1);
str_flag=1;
memset(str,0,1024*10);
memcpy(str,(char*)xmlbuff,buffersize);
str_flag=0;
xmlFree(xmlbuff); 
xmlFreeDoc(doc);//释放xml解析库所用资源
xmlCleanupParser();
return 0; 
}


void *get_lift_info()
{
	char *s;
	int x;
	struct sockaddr_in servaddr, cliaddr;
	socklen_t cliaddr_len;
	int sockfd, connfd_temp, tcp_socket_readlen;
	char buf[100];
	struct timeval outtime;
	memset(buf,0,100);
	outtime.tv_sec = 0;
	outtime.tv_usec = 1000;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	setsockopt(sockfd, SOL_SOCKET,SO_RCVTIMEO, &outtime,sizeof(outtime));
	
	int opt = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(6666);
	bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	listen(sockfd, 4);

	while(1)
	{
		tcp_socket_readlen=0;
		cliaddr_len = sizeof(cliaddr);
		tcp_socket_readlen=recvfrom(sockfd, buf, 100, 0, (struct sockaddr *)&cliaddr, &cliaddr_len);
		if(tcp_socket_readlen>0)
		{
			
			if( (s=strstr(buf,"currentmedia"))!=NULL )
			{
				memset(currentmedia,0,40);
				memcpy(currentmedia, buf, s-buf-1);
				currentmedia[0]=' ';			
			
			}

			else if( (s=strstr(buf,"currentdownload"))!=NULL )
			{
				printf("buf:%s\n",buf);
				memset(currentdownload,0,40);
				memcpy(currentdownload, buf, s-buf-1);
				printf("currentdownload=%s\n",currentdownload);
				currentdownload[0]=' ';			
			
			}

			else if( (s=strstr(buf,"net_status"))!=NULL )
			{
				memset(net_status,0,4);
				net_status[0]='4';
				net_status[1]='\0';		
			}
			else
			{
				//printf("\n");

				//for(x = 0;x<14;x++)
				//	printf("%2x ",buf[x]);
				//printf("\n");

				memset(botrunstart,0,2);
				sprintf(botrunstart,"%c",buf[1]);
				
				memset(botfloor,0,4);
				sprintf(botfloor,"%c%c%c",buf[2],buf[3],buf[4]);
					//printf("botfloor:%s\n",botfloor);	
				memset(botstart,0,2);
				sprintf(botstart,"%c",buf[5]);

				memset(botdoorstart,0,2);
				sprintf(botdoorstart,"%c",buf[6]);
				

			}
			
			parse_xml_file1(str1,sizeof(str1));
			memset(buf,0,100);
		
		}
		usleep(1000);
		//sleep(2);
		//printf("xiancheng%d,%d\n",getpid(),getppid());
	}

}

int main(int argc, char *argv[])
{
	struct sockaddr_in servaddr;
	int sockfd, n;
	FILE * t_fd;
	struct timeval outtime;
	struct stat stat;

	struct hostent *host;
	char serverip[40];
	int net_flag=0;

	fd_set rfds,wfds;
	int retval, maxfd = -1;  

	FILE *server_fp=fopen("/v4asys/server_ip","r");
	memset(serverip,0,40);
	if(server_fp!=NULL)
	{	     
		fgets(serverip,40,server_fp);
		fclose(server_fp);
	}

	creat_xml_file();

	memset(str,0,1024*10);
	t_fd = fopen("/info.xml","r");
	if ((fread(str, 1024*10,1,t_fd)) == -1)
	{
		printf("Read Failed.\n");
		fclose(t_fd);
		return 0;
	}
	else
	{
		memset(str1,0,1024*10);
		memcpy(str1,str,1024*10);

	}
	fclose(t_fd);

	pthread_t tid_get_lift;	
	pthread_create(&tid_get_lift,NULL,get_lift_info,NULL); 

	if(NULL == (host=gethostbyname(serverip)))
	{
		return -1;
	}
	
	if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		printf("create socket error\n");
	    	return 0;
	}

	//int flags = fcntl(sockfd, F_GETFL, 0);
	//fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

	//outtime.tv_sec = 3;
	//outtime.tv_usec = 0;

	//setsockopt(sockfd, SOL_SOCKET,SO_RCVTIMEO, &outtime,sizeof(outtime));
	//setsockopt(sockfd, SOL_SOCKET,SO_SNDTIMEO, &outtime,sizeof(outtime));

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr = *((struct in_addr *)host->h_addr);
	//inet_pton(AF_INET, "192.168.2.122", &servaddr.sin_addr);
	servaddr.sin_port = htons(SERV_PORT);


	if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
		printf("connect error\n");
		close(sockfd);
	   	return 0;
	}
	int flags = fcntl(sockfd, F_GETFL, 0);
	fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);	
	while(1)
	{
	
	FD_ZERO(&rfds);
	FD_ZERO(&wfds);            
    maxfd = 0;  
    FD_SET(sockfd, &rfds);
	FD_SET(sockfd, &wfds); 
    if (sockfd > maxfd)  
    	maxfd = sockfd;  
              
    outtime.tv_sec = 10;
	outtime.tv_usec = 0;             
    retval = select(maxfd + 1, &rfds, &wfds, NULL, &outtime);  
    
    if(retval == -1)
    {
    	close(sockfd);
		return -1;
    
    }
    else if(retval == 0)
    {
    	continue;
    }
	memset(buffer,0,1024*10);
	if (FD_ISSET(sockfd, &rfds))
	{			
		n = recv(sockfd, buffer, 1024*10, 0);	
		if(n>0)
		{
		    	parse_xml_file(buffer,n);
			net_flag = 0;
		}
		else
		{
			printf("\n########\nrecv 0 byte\n########\n");
			//close(sockfd);
			//return -1;
			net_flag++;
			if(net_flag>=5)
			{
				close(sockfd);
				return -1;
			}
			printf("recv net_flag=%d\n",net_flag);
		}
				
	}
	else
	{
		net_flag++;
		if(net_flag>=5)
		{
			close(sockfd);
			return -1;
		}
		printf("net_flag=%d,mediavolume=%s\n",net_flag,mediavolume);
	}

	if (FD_ISSET(sockfd, &wfds))
	{
		//printf("send msg .............!\n");
		while(str_flag)
			usleep(1);
		str_flag = 1;
		if((n=send(sockfd, str, strlen(str) + 1, 0)) <= 0)
		{
			printf("send msg failed!\n");
			printf("sendsize=%d\n",n);
		}
		str_flag = 0;
	}
	sleep(3);
	printf("main thread  botfloor:%s\n",botfloor);	
	}
	close(sockfd);
	pthread_join(tid_get_lift,NULL);
	xmlCleanupParser();
	return 0;
}

